package main

import (
    "io"
    "log"
    "os"
    "net/http"
    "html/template"
    "io/ioutil"
)

const (
    UPLOAD_DIR = "./uploads"
)

func uploadHandler(w http.ResponseWriter, r* http.Request) {
    if r.Method == "GET" {
        t, _ := template.ParseFiles("upload.html")
        t.Execute(w, nil)
    } else {
        f, h, _ := r.FormFile("image")
        filename := h.Filename
        log.Printf("upload file: %s", filename)
        defer f.Close()

        t, _ := os.Create(UPLOAD_DIR + "/" + filename)
        defer t.Close()

        _, err := io.Copy(t, f)
        if err != nil {
            log.Println("io.Copy error:", err.Error())
            return
        }

        http.Redirect(w, r, "view?id=" + filename, http.StatusFound)
    }
}

func viewHandler(w http.ResponseWriter, r* http.Request) {
    imageId := r.FormValue("id")
    imagePath := UPLOAD_DIR + "/" + imageId
    w.Header().Set("Content-Type", "image")
    log.Println("Get file: %s", imagePath)
    http.ServeFile(w, r, imagePath)
}

func listHandler(w http.ResponseWriter, r* http.Request) {
    fileInfoArr, err := ioutil.ReadDir(UPLOAD_DIR)
    if err != nil {
        log.Println("ReadDir err:", err.Error())
    }

    locals := make(map[string] interface{})
    images := []string{}

    for _, fileInfo := range fileInfoArr {
        log.Println("list file:", fileInfo)
        images = append(images, fileInfo.Name())
    }

    locals["images"] = images

    t, _ := template.ParseFiles("list.html")
    t.Execute(w, locals)
}

func isDirExists(path string) bool {
    fi, err := os.Stat(path)
    if err != nil {
        return os.IsExist(err)
    } else {
        return fi.IsDir()
    }
}

func main() {
    if isDirExists(UPLOAD_DIR) == false {
        os.Mkdir(UPLOAD_DIR, 0755)
    }
    http.HandleFunc("/upload", uploadHandler)
    http.HandleFunc("/view", viewHandler)
    http.HandleFunc("/", listHandler)

    log.Println("Listen on 0.0.0.0:9090")
    err := http.ListenAndServe("0.0.0.0:9090", nil)
    if err != nil {
        log.Fatal("ListenAndServe:", err.Error())
    }
}

